package com.enation.app.javashop.core.promotion.shetuan.service.impl;

import com.alibaba.fastjson.JSON;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.client.trade.OrderClient;
import com.enation.app.javashop.core.goods.model.dos.GoodsDO;
import com.enation.app.javashop.core.goodssearch.util.SortContainer;
import com.enation.app.javashop.core.member.model.dos.LeaderDO;
import com.enation.app.javashop.core.member.service.LeaderManager;
import com.enation.app.javashop.core.promotion.shetuan.model.dos.ShetuanOrderDO;
import com.enation.app.javashop.core.promotion.shetuan.model.vo.ShetuanOrderStatisticVO;
import com.enation.app.javashop.core.promotion.shetuan.model.vo.ShetuanOrderVO;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanOrderManager;
import com.enation.app.javashop.core.shop.model.dos.ShopCatDO;
import com.enation.app.javashop.core.shop.model.vo.ShopCatItem;
import com.enation.app.javashop.core.statistics.util.DateUtil;
import com.enation.app.javashop.core.trade.order.model.dos.OrderDO;
import com.enation.app.javashop.core.trade.order.model.dto.ShetuanOrderQueryParam;
import com.enation.app.javashop.core.trade.order.model.enums.*;
import com.enation.app.javashop.core.trade.order.model.vo.OrderDetailVO;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.util.BeanUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import com.google.common.collect.Maps;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 社区团购订单
 */
@Service
public class ShetuanOrderManagerImpl implements ShetuanOrderManager {
    protected final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport tradeDaoSupport;

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private LeaderManager leaderManager;

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public ShetuanOrderDO createOrder(OrderDO orderDO) {
        ShetuanOrderDO shetuanOrderDO = new ShetuanOrderDO();
        // 自提站点信息
        shetuanOrderDO.setLeaderId(-1);
        if(orderDO.getLeaderId()!=null){
            LeaderDO leaderDO = leaderManager.getById(orderDO.getLeaderId());
            shetuanOrderDO.setLeaderId(leaderDO.getLeaderId());
            shetuanOrderDO.setLeaderName(leaderDO.getLeaderName());
            shetuanOrderDO.setLeaderMemberId(leaderDO.getMemberId());
            shetuanOrderDO.setPickAddress(leaderDO.getAddress());
            shetuanOrderDO.setLeaderMobile(leaderDO.getLeaderMobile());
            shetuanOrderDO.setSiteName(leaderDO.getSiteName());
            shetuanOrderDO.setSiteType(leaderDO.getSiteType());
        }
        // 订单信息
        shetuanOrderDO.setOrderSn(orderDO.getSn());
        shetuanOrderDO.setOrderStatus(orderDO.getOrderStatus());
        shetuanOrderDO.setBuyerName(orderDO.getShipName());
        shetuanOrderDO.setSellerId(orderDO.getSellerId());

        shetuanOrderDO.setBuyerMemberId(orderDO.getMemberId());
        shetuanOrderDO.setBuyerMemberName(orderDO.getMemberName());

        shetuanOrderDO.setOrderId(orderDO.getOrderId());
        shetuanOrderDO.setBuyerName(orderDO.getShipName());
        shetuanOrderDO.setBuyerMobile(orderDO.getShipMobile());
        shetuanOrderDO.setCreateTime(DateUtil.getDateline());
        shetuanOrderDO.setOrderPrice(orderDO.getOrderPrice());
        shetuanOrderDO.setCommissionType(CommissionTypeEnum.LEADER_COMMISSION.name());

        tradeDaoSupport.insert(shetuanOrderDO);

        shetuanOrderDO.setId(tradeDaoSupport.getLastId("es_shetuan_order"));

        return shetuanOrderDO;
    }

    @Override
    public ShetuanOrderDO confirm(OrderDO orderDO) {
        // 查询社区团购订单(没有新增，防止漏单)
        ShetuanOrderDO shetuanOrderDO = tradeDaoSupport.queryForObject("select * from es_shetuan_order where order_id = ?", ShetuanOrderDO.class, orderDO.getOrderId());
        if (shetuanOrderDO == null) {
            shetuanOrderDO = this.createOrder(orderDO);
        }
        return shetuanOrderDO;
    }

    /**
     * 按月、按日统计社区团购订单数据
     */
    @Override
    public Page<ShetuanOrderStatisticVO> statistic(ShetuanOrderQueryParam shetuanOrderQueryParam) {
        String timeRegex = shetuanOrderQueryParam.getType() == 0 ? "%Y%m%d" : "%Y%m";
        String sql = "SELECT count( * ) orderNum,sum( temp.order_price ) orderPriceSum,sum( temp.leader_commission )  commissionSum,temp.ss_time ssTime FROM " +
                "( SELECT *, FROM_UNIXTIME( create_time, ? ) AS ss_time FROM es_shetuan_order WHERE leader_member_id=? and create_time>? and create_time< ?) AS temp " +
                "GROUP BY temp.ss_time";
        Page<ShetuanOrderStatisticVO> page = tradeDaoSupport.queryForPage(sql, shetuanOrderQueryParam.getPageNo(), shetuanOrderQueryParam.getPageSize(), ShetuanOrderStatisticVO.class,
                timeRegex, shetuanOrderQueryParam.getLeaderMemberId(), shetuanOrderQueryParam.getStartTime(), shetuanOrderQueryParam.getEndTime());
        return page;
    }

    /**
     * 汇总求和
     *
     * @param shetuanOrderQueryParam
     * @return
     */
    @Override
    public ShetuanOrderStatisticVO statisticAll(ShetuanOrderQueryParam shetuanOrderQueryParam) {
        String sql = " SELECT sum( order_price ) orderPriceSum,sum( leader_commission )  commissionSum ,count(1)   orderNum FROM es_shetuan_order " +
                "WHERE leader_member_id=? and create_time>? and create_time< ? ";
        ShetuanOrderStatisticVO shetuanOrderStatisticVO = tradeDaoSupport.queryForObject(sql, ShetuanOrderStatisticVO.class, shetuanOrderQueryParam.getLeaderMemberId(), shetuanOrderQueryParam.getStartTime(), shetuanOrderQueryParam.getEndTime());
        return shetuanOrderStatisticVO.getOrderNum() == null ? new ShetuanOrderStatisticVO() : shetuanOrderStatisticVO;
    }

    @Override
    public Page<ShetuanOrderVO> queryPage(ShetuanOrderQueryParam shetuanOrderQueryParam) {

        StringBuilder sql = new StringBuilder("  SELECT o.*,es.order_sn,es.remark, " +
                " es.leader_commission,es.commission_rate,es.update_time,es.site_name,es.site_type,  " +
                " es.st_order_status,es.leader_member_id,es.commission_type,es.buyer_member_id,es.buyer_member_name,es.leader_name,es.leader_mobile, " +
                " m.real_name,m.mobile ,ss.sn as sorting_seq, ss.bat_no as sorting_batch,l.province,l.city,l.county,l.town,l.address,l.street,esm.nickname as member_nick_name   FROM es_shetuan_order  es  " +
                " left join es_order o  ON es.order_id=o.order_id  " +
                " left join es_sorting_serial  ss  ON o.sn=ss.order_sn  " +
                " LEFT JOIN es_distribution dis ON es.buyer_member_id = dis.member_id " +
                " LEFT JOIN es_member m ON dis.member_id_lv1 = m.member_id " +
                " LEFT JOIN es_leader l ON l.leader_id = es.leader_id " +
                " LEFT JOIN es_member esm on esm.member_id =  es.buyer_member_id WHERE 1=1 ");
        List<Object> term = new ArrayList<>();

        // 订单号查询忽略其他条件
        if (shetuanOrderQueryParam.getOrderSn() != null) {
            sql.append(" and o.sn like ?");
            term.add("%" + shetuanOrderQueryParam.getOrderSn() + "%");

            String sort=getSort(shetuanOrderQueryParam.getOrderFields());
            if (!StringUtil.isEmpty(sort)) {
                sql.append(" order by ").append(sort).append(" ");
            }


            Page<ShetuanOrderVO> page = tradeDaoSupport.queryForPage(sql.toString(), shetuanOrderQueryParam.getPageNo(), shetuanOrderQueryParam.getPageSize(), ShetuanOrderVO.class, term.toArray());
            List<ShetuanOrderVO> data = page.getData();
            for (ShetuanOrderVO shetuanOrderVO : data) {
                shetuanOrderVO.resetStatusField();
            }
            return page;
        }

        // 关键字查询忽略其他条件
        if (shetuanOrderQueryParam.getKeyword() != null) {
            sql.append(" and (o.sn like ? or o.items_json like ? )");
            term.add("%" + shetuanOrderQueryParam.getKeyword() + "%");
            term.add("%" + shetuanOrderQueryParam.getKeyword() + "%");

            String sort=getSort(shetuanOrderQueryParam.getOrderFields());
            if (!StringUtil.isEmpty(sort)) {
                sql.append(" order by ").append(sort).append(" ");
            }

            Page<ShetuanOrderVO> page = tradeDaoSupport.queryForPage(sql.toString(), shetuanOrderQueryParam.getPageNo(), shetuanOrderQueryParam.getPageSize(), ShetuanOrderVO.class, term.toArray());
            List<ShetuanOrderVO> data = page.getData();
            for (ShetuanOrderVO shetuanOrderVO : data) {
                shetuanOrderVO.resetStatusField();
            }
            return page;
        }

        String orderStatus = shetuanOrderQueryParam.getOrderStatus();
        if (!StringUtil.isEmpty(orderStatus)) {
            OrderTagEnum tagEnum = OrderTagEnum.valueOf(orderStatus);
            switch (tagEnum) {
                case ALL:
                    break;
                //待付款
                case WAIT_PAY:
                    // 非货到付款的，未付款状态的可以结算 OR 货到付款的要发货或收货后才能结算
                    sql.append(" and  ( o.order_status = '" + OrderStatusEnum.CONFIRM + "' )");
                    break;

                //待发货
                case WAIT_SHIP:
                    // 普通订单：
                    //      非货到付款的，要已结算才能发货 OR 货到付款的，已确认就可以发货
                    sql.append(" and (");
                    sql.append(" o.order_status='" + OrderStatusEnum.PAID_OFF + "'");
                    sql.append(")");
                    break;

                //待收货
                case WAIT_ROG:
                    sql.append(" and o.order_status='" + OrderStatusEnum.SHIPPED + "'");
                    break;

                //待评论
                case WAIT_COMMENT:
                    sql.append(" and o.ship_status='" + ShipStatusEnum.SHIP_ROG + "' and o.comment_status='" + CommentStatusEnum.UNFINISHED + "' ");
                    break;

                //待追评
                case WAIT_CHASE:
                    sql.append(" and o.ship_status='" + ShipStatusEnum.SHIP_ROG + "' and o.comment_status='" + CommentStatusEnum.WAIT_CHASE + "' ");
                    break;

                //已取消
                case CANCELLED:
                    sql.append(" and o.order_status='" + OrderStatusEnum.CANCELLED + "'");
                    break;

                //售后中
                case REFUND:
                    sql.append(" and o.service_status='" + ServiceStatusEnum.APPLY + "'");
                    break;

                //已完成
                case COMPLETE:
                    sql.append(" and o.order_status='" + OrderStatusEnum.COMPLETE + "'");
                    break;
                default:
                    break;
            }
        }

        if (shetuanOrderQueryParam.getLeaderName() != null) {
            sql.append(" and es.leader_name like ? ");
            term.add("%" + shetuanOrderQueryParam.getLeaderName() + "%");
        }
        // 配送方式
        if (shetuanOrderQueryParam.getShippingType() != null) {
            sql.append(" and o.shipping_type = ? ");
            term.add(shetuanOrderQueryParam.getShippingType());
        }
        // 打印状态
        if (StringUtil.notEmpty(shetuanOrderQueryParam.getPrintTimes())) {
            if ("1".equals(shetuanOrderQueryParam.getPrintTimes())) {
                sql.append(" and o.print_times > 0 ");
            } else {
                sql.append(" and o.print_times = 0 ");
            }
        }

        //会员昵称查询
        String memberNickName = shetuanOrderQueryParam.getMemberNickName();
        if(StringUtil.notEmpty(memberNickName)){
            sql.append(" and esm.nickname like ? ");
            term.add("%" + memberNickName + "%");
        }
        //所属团长
        String leaderTeam = shetuanOrderQueryParam.getLeaderTeam();
        if(StringUtil.notEmpty(leaderTeam)){
            sql.append(" and m.real_name like ? ");
            term.add("%" + leaderTeam + "%");
        }

        if (shetuanOrderQueryParam.getShipName() != null) {
            sql.append(" and o.ship_name like ? ");
            term.add("%" + shetuanOrderQueryParam.getShipName() + "%");
        }
        if (shetuanOrderQueryParam.getShipMobile() != null) {
            sql.append(" and o.ship_mobile like ? ");
            term.add("%" + shetuanOrderQueryParam.getShipMobile() + "%");
        }
        if (shetuanOrderQueryParam.getSiteName() != null) {
            //updateTime 2020年9月17日 14:08:08 王志杨 解决按照站点名称site_name无法条件查询问题
            sql.append(" and es.site_name like ? ");
            term.add("%" + shetuanOrderQueryParam.getSiteName() + "%");
        }
        if (shetuanOrderQueryParam.getStartTime() != null && shetuanOrderQueryParam.getEndTime() != null) {
            sql.append(" and o.create_time >= ? and o.create_time <= ?");
            term.add(shetuanOrderQueryParam.getStartTime());
            term.add(shetuanOrderQueryParam.getEndTime());
        }
        if (shetuanOrderQueryParam.getSellerId() != null) {
            sql.append(" and o.seller_id=?");
            term.add(shetuanOrderQueryParam.getSellerId());
        }
        if (shetuanOrderQueryParam.getMemberId() != null) {
            sql.append(" and o.member_id=?");
            term.add(shetuanOrderQueryParam.getMemberId());
        }

        String sort=getSort(shetuanOrderQueryParam.getOrderFields());
        if (!StringUtil.isEmpty(sort)) {
            sql.append(" order by ").append(sort).append(" ");
        }

        Page<ShetuanOrderVO> page = tradeDaoSupport.queryForPage(sql.toString(), shetuanOrderQueryParam.getPageNo(), shetuanOrderQueryParam.getPageSize(), ShetuanOrderVO.class, term.toArray());
        List<ShetuanOrderVO> data = page.getData();
        for (ShetuanOrderVO shetuanOrderVO : data) {
            shetuanOrderVO.resetStatusField();
        }
        return page;
    }

    private String getSort(List<String> orderFields) {
        StringBuilder sortBuilder=new StringBuilder();
        if (CollectionUtils.isEmpty(orderFields)) {
            sortBuilder.append(" create_time desc");
        }else {
            List<Map<String, String>> shetuanOrderSortList = SortContainer.getShetuanOrderSortList();
            Map<String, String> sortMap = Maps.newHashMap();
            for (String sortField : orderFields) {
                String[] sortar = sortField.split("_");
                String sortKey = sortar[0];
                String sortType = sortar[1];
                sortMap.put(sortKey,sortType);
            }
            for (Map<String, String> orderedSort : shetuanOrderSortList) {
                String sortType = sortMap.get(orderedSort.get("name"));
                if(sortType!=null){
                    sortBuilder.append(orderedSort.get("id")).append(" ").append(sortType).append(",");
                }
            }
        }
        String sortStr = sortBuilder.toString();
        return  sortStr.endsWith(",")?sortStr.substring(0,sortStr.length()-1):sortStr;
    }


    @Override
    public ShetuanOrderDO getByOrderId(Integer orderId) {
        String sql = "select * from es_shetuan_order where order_id=?";
        ShetuanOrderDO shetuanOrderDO = tradeDaoSupport.queryForObject(sql, ShetuanOrderDO.class, orderId);
        return shetuanOrderDO;
    }

    /**
     * 计算订单退款
     */
    @Override
    public void calReturnCommission(String orderSn, Double refundPrice) {
        OrderDetailVO orderVO = orderClient.getOrderVO(orderSn);
        if (!orderVO.getOrderType().equals(OrderTypeEnum.shetuan.name())) {
            return;
        }
        ShetuanOrderDO shetuanOrderDO = tradeDaoSupport.queryForObject("select * from es_shetuan_order where order_id=?", ShetuanOrderDO.class, orderVO.getOrderId());
        // 计算退款金额
        shetuanOrderDO.setLeaderReturnCommission(shetuanOrderDO.getLeaderCommission());
        shetuanOrderDO.setRemark("【订单退款】-退款金额："+refundPrice);
        shetuanOrderDO.setStOrderStatus(StOrderStatusEnum.CANCELLED.name());
        tradeDaoSupport.update(shetuanOrderDO,shetuanOrderDO.getId());
    }

    @Override
    public void updateShetuanOrderDO(ShetuanOrderDO shetuanOrderDO) {
        tradeDaoSupport.update(shetuanOrderDO,shetuanOrderDO.getId());
    }

    @Override
    public void initShopCat(Integer sellerId) {
        List<GoodsDO> goodsDOS = this.tradeDaoSupport.queryForList("select * from es_goods where seller_id=?", GoodsDO.class, sellerId);
        List<Object[]> batchArgs = new ArrayList<>();
        for (GoodsDO goodsDO : goodsDOS) {
            if (goodsDO.getShopCatId() == null) {
                continue;
            }
            ShopCatDO shopCatDO = this.tradeDaoSupport.queryForObject(ShopCatDO.class, goodsDO.getShopCatId());
            if (shopCatDO == null) {
                continue;
            }
            ShopCatItem shopCatItem = new ShopCatItem();
            BeanUtil.copyProperties(shopCatDO,shopCatItem);
            List<ShopCatItem> shopCatItems = Arrays.asList(shopCatItem);

            batchArgs.add(new Object[]{
                    JSON.toJSONString(shopCatItems),
                    goodsDO.getGoodsId()});
        }

        this.jdbcTemplate.batchUpdate("UPDATE es_goods SET shop_cat_items=? WHERE goods_id = ? ",batchArgs);

    }


}
